package org.mclll.xwangplugin.plant.listener;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Dispenser;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockGrowEvent;
import org.bukkit.event.block.BlockSpreadEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.mclll.xwangplugin.MclllCustom;
import org.mclll.xwangplugin.log.LogUtil;
import org.mclll.xwangplugin.log.LoggerFactory;
import org.mclll.xwangplugin.log.PlantLog;
import org.mclll.xwangplugin.plant.config.PlantConfig;

import java.util.Collection;

/**
 * @author: geduo
 * @date: 2023/9/19 15:56
 */
public class PlantListener implements Listener {

    private final MclllCustom plugin;

    private final LogUtil log;

    public PlantListener(MclllCustom plugin) {
        this.plugin = plugin;
        this.log = LoggerFactory.get(PlantLog.class);
    }

    @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
    public void onBlockGrow(BlockSpreadEvent event) {
        Material type = event.getNewState().getType();
        log.info("{0}", type);
        event.setCancelled(platGrowController(event.getBlock(), type));
    }

    @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
    public void onBlockGrow(BlockGrowEvent event) {
        Block block = event.getBlock();
        // 获取方块类型
        Material plantType = null;
        if (Material.AIR == block.getType() || Material.WATER == block.getType()) {
            plantType = event.getNewState().getType();
        } else {
            plantType = block.getType();
        }
        ;
        event.setCancelled(
                platGrowController(block, plantType)
        );
    }

    private boolean platGrowController(Block block,Material plantType) {
        Location location = block.getLocation();
        // 让骨粉正常工作
        if (useBoneMeal(location, block)) {
            return false;
        }
        // 生态群系
        Biome biome = block.getWorld().getBiome(location);
        log.info("{0}在{1}准备生长", plantType.name(), biome.name());
        PlantConfig.PlantGrowControl plantGrowControl = PlantConfig.get(biome, plantType);
        if (plantGrowControl != null) {
            double random = Math.random();
            log.info("计算后概率{0}随机概率为{1}",plantGrowControl.getProbability(), random);
            if (random < plantGrowControl.getProbability()) {
                log.info("{0}生长失败", plantType.name());
                return true;
            }
        }
        return false;
    }

    private boolean useBoneMeal(Location location, Block block) {
        if (playerUse(location)) {
            return true;
        }
        if (DispenserUseBoneMeal(block, location)) {
            return true;
        }
        return false;
    }

    private boolean playerUse(Location location) {
        Collection<Player> nearbyPlayers = location.getNearbyPlayers(4);
        if (!nearbyPlayers.isEmpty()) {
            for (Player nearbyPlayer : nearbyPlayers) {
                if (nearbyPlayer.getInventory().getItem(EquipmentSlot.HAND).getType() == Material.BONE_MEAL
                        || nearbyPlayer.getInventory().getItem(EquipmentSlot.OFF_HAND).getType() == Material.BONE_MEAL
                ) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean DispenserUseBoneMeal(Block plant, Location location) {
        World world = plant.getWorld();
        Block[] blocks = {world.getBlockAt(location.clone().add(1, 0, 0)),
                world.getBlockAt(location.clone().add(-1, 0, 0)),
                world.getBlockAt(location.clone().add(0, 1, 0)),
                world.getBlockAt(location.clone().add(0, 0, 1)),
                world.getBlockAt(location.clone().add(0, 0, -1))};
        for (Block block : blocks) {
            if (block.getType() == Material.DISPENSER) {
                BlockState blockState = block.getState();
                BlockData blockData = block.getBlockData();
                if (blockState instanceof Dispenser) {
                    if (((org.bukkit.block.data.type.Dispenser) blockData).getFacing() != block.getFace(plant)) {
                        continue;
                    }
                    for (ItemStack itemStack : ((Dispenser) blockState).getInventory()) {
                        if (itemStack == null) {
                            continue;
                        }
                        if (itemStack.getType() == Material.BONE_MEAL) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
}
